<template>
	<view class="image-drag-sort">
		<view class="inner">
			<movable-area class="movable-area">
				<view :class="delayTypes ? 'item delayTypes' : 'item'" :style="{ 'margin-right': parentStyle }"
					v-for="(item, index) in lists" :key="index" @click.stop="imageTap(index, item)" @longpress="longtap"
					@touchend="touchend" @touchmove.stop="touchm">
					<image class="img" :src="imgHeader(resizeImage(item.url))" mode="aspectFill"
						v-if="item.type === 'image'">
					</image>
					<image class="img" src="/static/images/video.png" mode="aspectFill" v-else></image>
					<image class="priview" src="/static/images/preview.png" v-if="item.type == 'image'"></image>
				</view>
				<view class="img-upload-btn item" :style="{ 'margin-right': parentStyle }" @click="uploadImg"
					v-if="(lists.length < max && !active && !disabled) || showUploadBtn">
					<image src="../../static/images/camera.png"></image>
					<view>{{ tips }}</view>
				</view>

				<view class="img-upload-btn item" :style="{ 'margin-right': parentStyle }" @click="uploadVideo"
					v-if="isVideoShow && lists.length < max && !active && !disabled">
					<image src="/static/images/vicon.png"></image>
					<view>上传视频</view>
				</view>

				<movable-view class="movable-view" :x="x" :y="y" direction="all" damping="5000" friction="1"
					v-show="active">
					<view class="item-move" :class="{ 'item-move-active': active }">
						<image class="img" :src="imgHeader(lists[beginIndex])" mode="aspectFill"></image>
					</view>
				</movable-view>
			</movable-area>
		</view>
		<!-- <view class="prompt">点击预览/删除图片，长按拖拽排序，共{{ lists.length }}张图片</view> -->
		<uni-popup ref="popup" :mask-click="true" type="bottom" v-if="lists.length < max && !active && !disabled"
			@change="changePopUp">
			<view class="bottomPop">
				<view class="bottomPop_content">
					<view class="bottomPop_item" @click="takePhoto(index)" v-for="(item, index) in customList"
						:key="index">
						{{ item.name }}
						<view class="tips">
							<view v-for="(v, i) in item.tips" :key="i">{{ v }}</view>
						</view>
					</view>
				</view>

				<view class="cancle flex" @click="() => {
					$refs.popup.close();
				}
				">
					取消
				</view>
			</view>
		</uni-popup>

	</view>
</template>
<script>
import { mapState } from 'vuex';
// 拖拽范围的总宽度
let wrapW = 0,
	// 拖拽范围的总高度
	wrapH = 0,
	// 可拖拽区域宽度
	wrapW2 = 0,
	// 可拖拽区域高度
	wrapH2 = 0,
	// 拖拽范围的上边界坐标
	wrapTop = 0,
	// 拖拽范围的左边界坐标
	wrapLeft = 0,
	// 可拖拽范围的上边界坐标
	wrapDragTop = 0,
	// 可拖拽范围的左边界坐标
	wrapDragLeft = 0,
	// 拖拽元素的宽
	itemW = 0,
	// 拖拽元素的高
	itemH = 0,
	// 拖拽元素的列数
	itemXNun = 0;
export default {
	name: 'image-drag-sort',
	components: {
		// unipopup
	},
	data() {
		return {
			lists: this.list,
			imgIndex: 0,
			// 是否拖拽状态
			active: false,
			// 是否可拖拽
			flag: false,
			x: 0,
			y: 0,
			// 当前拖拽元素的索引
			beginIndex: null,
			fileType: '1'
		};
	},
	props: {
		parentStyle: {
			type: String,
			default: '20rpx'
		},
		// 延期所有页面
		delayTypes: {
			type: Boolean,
			default: false
		},
		// 不可编辑
		disabled: {
			type: Boolean,
			default: false
		},
		tips: {
			type: String,
			default: '点击拍照'
		},
		padding: {
			type: String,
			default: '30rpx'
		},
		list: {
			type: Array,
			default: function () {
				return [];
			}
		},
		uploadType: {
			// 1两者都有 2只给拍照 3只给选择相册
			type: String,
			default: '1'
		},
		keyName: {
			type: String,
			default: ''
		},
		max: {
			type: [Number, String],
			default: 9
		},
		resize: {
			type: Object,
			default: () => {
				return { width: 64, height: 64 };
			}
		},
		imgdel: {
			type: Boolean,
			default: false
		},
		// 订单类型 默认为0使用默认uni.showActionSheet，如果1自定义
		customType: {
			type: Boolean,
			default: false
		},
		customList: {
			type: Array,
			default: () => {
				return [
					{ name: '拍摄', tips: ['建议时间长度控制在两分钟以内'] },
					{ name: '从手机相册选择', tips: ['建议时间长度控制在两分钟以内'] },
				];
			}

		},
		// 视频上传
		isVideoShow: {
			type: Boolean,
			default: true,
		},
		// 启用删除
		showDel: {
			type: Boolean,
			default: true,
		},
		// 启用重新拍照
		showReset: {
			type: Boolean,
			default: true,
		},
		// 启用上传按钮
		showUploadBtn: {
			type: Boolean,
			default: false,
		},
		uploadOptions: {
			type: Object,
			default: () => {
				return {
					// imgId:'',// fileName
					// contentType: '',// 文件类型
					// meta: {}, // 自定义参数
					// headers: {},// 请求头
					// callback: {},// 上传回调,小程序不可用
					// imageMaxSize: 1024 * 1024 * 10, // 上传文件大小限制
					// compress: {},// 图片压缩配置
					// onProgressUpdate: () => {},// 上传进度回调
				};
			}
		},
	},
	computed: {
		...mapState('user', ['userinfo']),
		imgList() {
			// console.log('lists', this.list);
			return this.list;
		},
	},
	mounted() {
		let l = this.lists.length;
		if (l) {
			// 有图片时初始化
			this.init();
		}
	},
	beforeDestroy() {
		uni.$off('uploadImg');
	},

	methods: {
		resizeImage(imageUrl) {
			if (!imageUrl) {
				return '';
			}
			if (imageUrl.indexOf('http') == -1) {
				return imageUrl;
			}
			let params = {};
			if (this.resize && this.resize.width && this.resize.height) {
				params.resize = `w_${this.resize.width},h_${this.resize.height}`;
			} else if (this.resize && this.resize.width) {
				params.resize = `w_${this.resize.width}`;
			} else if (this.resize && this.resize.height) {
				params.resize = `h_${this.resize.height}`;
			}
			return this.generateOssImageUrl(imageUrl, params);
		},
		changePopUp(e) {
			// console.log(e,'e的值')
			// eslint-disable-next-line vue/custom-event-name-casing
			this.$emit('getPopUpVisible', e.show);
		},
		init() {
			// 初始化数据
			// 设置拖拽区域信息
			let wrap = uni
				.createSelectorQuery()
				.in(this)
				.select('.inner');
			wrap.boundingClientRect(data => {
				// console.log(data)
				// 设置拖拽范围的总宽度
				wrapW = data.width;
				// 设置拖拽范围的总高度
				wrapH = data.height;
				// 设置拖拽范围的上边界坐标
				wrapTop = data.top;
				// 设置拖拽范围的左边界坐标
				wrapLeft = data.left;
				this.setNodeWH();
			}).exec();
		},
		setNodeWH() {
			// 设置拖拽元素的宽高
			// 获取拽拖元素的信息
			let item = uni
				.createSelectorQuery()
				.in(this)
				.select('.item');
			item.boundingClientRect(data => {
				// console.log(data)
				// 拖拽元素的宽度
				itemW = data.width;
				// 拖拽元素的高度
				itemH = data.height;
				this.setDragData();
			}).exec();
		},
		// 设置拖拽区域及元素配置
		setDragData() {
			// 设置拖拽范围上边距
			wrapDragTop = wrapTop + itemH / 2;
			// 设置可拖拽范围左边距
			wrapDragLeft = wrapLeft + itemW / 2;
			// 设置可拖拽区域宽度
			wrapW2 = wrapW - itemW;
			// 设置可拖拽区域高度
			wrapH2 = wrapH - itemH;
			// 设置拖拽元素的列数
			itemXNun = Math.round(wrapW / itemW) - 1;
		},
		longtap(e) {
			// 长按
			const left = e.currentTarget.offsetLeft,
				top = e.currentTarget.offsetTop;
			// 获取所在位置索引
			this.beginIndex = this.computationIndex({ left: left, top: top });
			this.x = left;
			this.y = top;
			this.active = true;
			this.flag = true;
		},
		computationIndex(e) {
			// 计算元素索引
			const left = e.left,
				top = e.top;
			// 计算拖拽元素所在的索引位置
			let index = 0,
				// 计算拖拽元素所在的横向索引位置
				x = Math.round(left / itemW),
				// 计算拖拽元素所在的纵向索引位置
				y = Math.round(top / itemH),
				num = itemXNun * y;
			if (x && !y) {
				// 第一行
				index = x;
			}
			if (y) {
				// 第一行以下
				index = x + y + num;
			}
			return index;
		},
		touchm(e) {
			// 拖拽过程
			if (this.flag) {
				let x = e.touches[0].pageX - wrapDragLeft,
					y = e.touches[0].pageY - wrapDragTop;
				if (x < 0) {
					x = 0;
				}
				if (x > wrapW2) {
					x = wrapW2;
				}
				if (y < 0) {
					y = 0;
				}
				if (y > wrapH2) {
					y = wrapH2;
				}
				this.x = x;
				this.y = y;
			}
		},
		touchend(e) {
			// 拖拽结束
			this.active = false;
			const left = e.currentTarget.offsetLeft,
				top = e.currentTarget.offsetTop;
			if (!this.flag || (this.x === left && this.y === top)) {
				return;
			}
			// 计算拖拽横向距离
			const x = this.x,
				// 计算拖拽纵向距离
				y = this.y,
				// 拖拽元素的总数量
				itemNum = this.lists.length - 1;
			// 获取所在位置索引
			let endIndex = this.computationIndex({ left: x, top: y });
			if (endIndex > itemNum) {
				endIndex = itemNum;
			}
			// 交换位置
			// 当前拖拽元素索引
			const beginIndex = this.beginIndex;
			let data = this.lists,
				tem = data[beginIndex];
			data[beginIndex] = data[endIndex];
			data[endIndex] = tem;
			this.flag = false;

			this.changeArray(this.lists);
		},
		imageTap(i, item) {
			if (this.disabled) {
				this.previewImage(i);
				return;
			}
			let that = this;
			this.imgIndex = i;
			// 图片点击事件
			let itemList = [];
			if (item.type === 'image') {
				itemList = ['查看大图'];
				if (this.showReset) {
					itemList.push('重新拍照');
				}
				if (this.showDel) {
					itemList.push('删除照片');
				}
				this.fileType = '1';
			} else {
				itemList = ['查看视频'];
				if (this.showReset) {
					itemList.push('重新拍摄');
				}
				if (this.showDel) {
					itemList.push('删除视频');
				}
				this.fileType = '2';
			}
			uni.showActionSheet({
				itemList: itemList,
				success(res) {
					if (res.tapIndex == 0) {
						// 预览
						that.previewImage(i);
					} else if (res.tapIndex == 1) {
						// 重新上传
						that.reLoadImage(i);
					} else if (res.tapIndex == 2) {
						// 删除
						that.imageDel(i);
					}
				}
			});
		},
		previewImage(i) {
			// 预览图片 
			this.$previewMedia({
				sources: this.lists,
				current: i
			});
		},
		imageDel(i) {
			let that = this;
			uni.showModal({
				content: '确定要删除该照片吗？',
				cancelText: '否',
				confirmText: '是',
				success(res) {
					if (res.confirm) {
						// 删除图片事件
						that.lists.splice(i, 1);
						if (that.imgdel) {
							// eslint-disable-next-line vue/custom-event-name-casing
							that.$emit('imgDels', i);
						} else {
							that.changeArray(that.lists);
						}
					}
				}
			});
		},

		imageUpload() {
			if (this.fileType === '2') {
				this.$refs.popup.open();
			} else {
				if (this.uploadType == '1') {
					let itemList = ['拍照上传', '从相册选择'];
					uni.showActionSheet({
						itemList: itemList,
						success: res => {
							this.chooseImage(res.tapIndex);
						}
					});
				} else if (this.uploadType == '2') {
					if (this.orderType === 1) {
						this.$refs.popup.open();

						// this.$emit('chooseUploadType')
					} else {
						this.chooseImage(0);
					}
				} else if (this.uploadType == '3') {
					this.chooseImage(1);
				}
			}
		},
		toCameraPage() {
			let pages = getCurrentPages();
			let pag = pages[pages.length - 1];
			if (pag.route && pag.route.indexOf('workOrders/detail') != -1) {
				uni.$emit('openCamera', {});
			} else {
				uni.navigateTo({
					url: '/pages/camera/camera',
					fail: (err) => {
						console.log(err);
					}
				});
			}
		},
		// 重新上传图片/视频
		reLoadImage(i) {
			let that = this;
			// index > 0 ? 'album' : 'camera';
			// let sourceType = 'camera';
			if (this.fileType === '1') {
				try {
					uni.$off('uploadImg');
				} catch (error) {
					console.log(error);
				}
				uni.$once('uploadImg', (path, imgId, options) => {
					uni.showLoading({
						title: '上传中',
						mask: true
					});
					let data = that.lists;
					that.http
						.upload(path, imgId, options)
						.then(res => {
							data.splice(i, 1, { url: res.data.link, type: this.fileType === '1' ? 'image' : 'video' });
							that.lists = data;
							that.changeArray(this.lists);
							uni.hideLoading();
						})
						.catch(() => {
							uni.hideLoading();
						});
				});
				this.toCameraPage();
			} else {
				uni.chooseVideo({
					sourceType: ['camera'],
					maxDuration: 60,
					camera: 'back',
					success: res => {
						uni.showLoading({
							title: '上传中',
							mask: true
						});
						console.log(res, '视频内容');
						let data = that.lists;
						let options = {};
						if (this.uploadOptions) options = this.uploadOptions;
						that.http
							.upload(res.tempFilePath, '', options)
							.then(res => {
								data.splice(i, 1, { url: res.data.link, type: that.fileType === '1' ? 'image' : 'video' });
								that.lists = data;
								that.changeArray(this.lists);
								uni.hideLoading();
							})
							.catch(() => {
								uni.hideLoading();
							});
					}
				});
			}
		},

		chooseImage(index) {
			// let _this = this;
			// 选择图片
			let count = this.max - this.lists.length,
				sourceType = index > 0 ? 'album' : 'camera';
			if (this.fileType === '1') {
				if (sourceType == 'camera') {
					try {
						uni.$off('uploadImg');
					} catch (error) {
						console.log(error);
					}
					uni.$once('uploadImg', (path, imgId, options) => {
						uni.hideLoading();
						setTimeout(() => {
							uni.showLoading({
								title: '上传中',
								mask: true
							});
						}, 100);
						this.upload([path], imgId, options);
					});
					this.toCameraPage();
					return;
				}

				// #ifndef H5
				uni.chooseImage({
					count: count,
					// ['original', 'compressed']
					sizeType: ['original'],
					sourceType: [sourceType],
					success: res => {
						uni.hideLoading();
						setTimeout(() => {
							uni.showLoading({
								title: '上传中',
								mask: true
							});
						}, 100);
						this.upload(res.tempFilePaths);
					}
				});
				// #endif

				// #ifdef H5
				window.sida.chooseImage({
					count: count,
					sizeType: ['original'], // ['original', 'compressed']
					sourceType: [sourceType],
					success: res => {
						uni.showLoading({
							title: '上传中',
							mask: true
						});
						this.upload(res.tempFilePaths);
					}
				});
				// #endif
			} else {
				uni.chooseVideo({
					sourceType: [sourceType],
					maxDuration: 60,
					camera: 'back',
					success: res => {
						uni.showLoading({
							title: '上传中',
							mask: true
						});
						this.upload(res.tempFilePath);
					}
				});
			}
		},
		async upload(e, imgId = '', options) {
			// 可多图上传，不需要的可改成单一上传 
			let data = this.lists;
			if (this.fileType == '1') {
				for (let i = 0, l = e.length; i < l; i++) {
					await this.http
						.upload(e[i], imgId, options)
						.then(res => {
							data.push({ url: res.data.link, type: 'image' });
						}
						).catch(err => {
							console.log('errors', err);
						});
				}
				// this.lists = data;
				// console.log(this.lists);
				// this.changeArray(this.lists, 'lists的值');
				// uni.hideLoading();
			} else {
				let options = {};
				if (this.uploadOptions) options = this.uploadOptions;
				await this.http
					.upload(e, '', options)
					.then(res => {
						data.push({ url: res.data.link, type: 'video' });
					}
					).catch(err => {
						console.log('errors', err);
					});
			}
			this.lists = data;
			this.changeArray(this.lists, 'lists的值');
			uni.hideLoading();
			// 可写上传图片方法或者将本地图片路径传给父组件
		},

		changeArray(list) {
			this.$emit('changeList', list, this.keyName);
		},
		takePhoto(index) {
			this.$refs.popup.close();
			this.chooseImage(index);
		},
		uploadImg() {
			this.fileType = '1';
			this.imageUpload();
		},
		uploadVideo() {
			this.fileType = '2';
			this.imageUpload();
		}
	},
	watch: {
		list() {
			this.lists = this.list;
			// 监听数组变化
			let l = this.list.length;
			if (l) {
				// 有图片或图片数量改变时重新初始化
				this.init();
			}
		}
	}
};
</script>

<style lang="scss" scoped>
.img {
	width: 100%;
	height: 100%;
}

.image-drag-sort {
	width: 100%;
	box-sizing: border-box;
}

.movable-area {
	width: 100%;
	height: auto;
	display: flex;

	flex-flow: wrap;
}

.item {
	width: 128rpx;
	height: 128rpx;
	/* flex: 0 0 31%; */
	position: relative;
	overflow: hidden;
	margin-bottom: 20rpx;
	// border-radius: 12upx;
	background: #ccc;
}

.delayTypes {
	width: 112rpx;
	background: #ccc;
}

.priview {
	position: absolute;
	bottom: 10rpx;
	right: 10rpx;
	width: 40rpx;
	height: 40rpx;
	z-index: 2;
}

.item {
	margin-right: 20rpx;
}

.img-upload-btn {
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	background-color: #fff;
	// border: 1rpx solid #e0e0e0;
	background-color: #f7f7f8;
	flex-wrap: wrap;
	color: $theme-color;
	font-size: 24rpx;

	image {
		width: 40rpx;
		height: 40rpx;
	}

	view {
		width: 100%;
		text-align: center;
	}
}

.img-upload-btn .icon {
	width: 48upx;
	height: 48upx;
}

.img-upload-btn .text {
	font-size: 24upx;
	color: #cccccc;
	margin-top: 10upx;
}

.movable-view {
	width: 130rpx;
	height: 130rpx;
	z-index: 33;
}

.item-move {
	width: 100%;
	height: 100%;
	overflow: hidden;
	// border-radius: 12upx;
}

.item-move-active {
	box-shadow: 0 0 30px #000;
}

.prompt {
	font-size: 24upx;
	line-height: 40upx;
	color: #999;
	margin-top: 28upx;
}

.bottomPop {
	background-color: #f2f2f2;

	.bottomPop_content {
		margin-bottom: 16rpx;

		.bottomPop_item {
			height: 162rpx;
			background: #ffffff;
			border-radius: 24rpx 24rpx 0rpx 0rpx;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			border-bottom: 2rpx solid rgba(0, 0, 0, 0.1);

			.tips {
				color: #999;
				font-size: 24rpx;
			}

		}

		:nth-last-child(1) {
			border-bottom: none;
		}
	}

	.cancle {
		height: 108rpx;
		background: #ffffff;
	}

}
</style>
